package com.nabi.library.contents.geom
{
	import com.yzi.utilitys.GeometryUtility;
	import com.yzi.utilitys.TransformUtility;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.geom.Transform;
	
	public class NativeTransform extends Transform implements ITransform
	{
		private var m_container:DisplayObject;
		private var m_matrix:Matrix;
		private var m_createdBounds:Rectangle;
		
		public function NativeTransform($container:DisplayObject)
		{
			super($container);
			SetTarget($container);
			m_matrix = new Matrix();
			Update();
		}
		
		public function Update(): void
		{
			var transform:Matrix = new Matrix();
			transform.identity();
			transform.concat(m_matrix);
			if(!m_container.transform) return;
			if(m_container.transform == this) {
				super.matrix = transform;
			} else {
				m_container.transform.matrix = transform;
			}
		}
		
		public function UpdateBound(): void
		{
			var matrix:Matrix = GetMatrix();
			matrix.invert();
			m_createdBounds = GeometryUtility.GetRectByMetrix(m_container.getRect(null), matrix);
		}
		
		public function GetMatrix(): Matrix { return m_matrix.clone(); }
		
		public function SetMatrix($matrix:Matrix): void
		{
			m_matrix = $matrix;
			Update();
			m_container.dispatchEvent(new Event(Event.CHANGE));
		}
		
		public function GetTarget(): DisplayObject { return m_container; }
		
		public function SetTarget($displayObject:DisplayObject): void
		{
			m_container = $displayObject;
			m_createdBounds = m_container.getBounds(m_container);
		}
		
		public function GetTransformMatrix(): Matrix { return m_container.transform.matrix; }
		
		public function GetBounds($coordinate:DisplayObject = null): Rectangle { return m_createdBounds; }
		
		public function get x(): Number { return GetMatrix().tx; }
		
		public function set x($value:Number): void 
		{
			var matrix:Matrix = GetMatrix();
			matrix.tx = $value;
			SetMatrix(matrix);
		}
		
		public function get y(): Number	{ return GetMatrix().ty; }
		
		public function set y($value:Number): void
		{
			var matrix:Matrix = GetMatrix();
			matrix.ty = $value;
			SetMatrix(matrix);
		}
		
		public function get width(): Number { return m_createdBounds.width * scaleX; }
		
		public function set width($value:Number):void { scaleX = $value / m_createdBounds.width; }
		
		public function get height(): Number { return m_createdBounds.height * scaleY; }
		
		public function set height($value:Number): void { scaleY = $value / m_createdBounds.height; }
		
		public function get scaleX(): Number { return TransformUtility.GetScaleX(GetMatrix()); }
		
		public function set scaleX($value:Number): void
		{
			var matrix:Matrix = GetMatrix();
			TransformUtility.SetScaleX(matrix, $value);
			SetMatrix(matrix);
		}
		
		public function get scaleY(): Number { 	return TransformUtility.GetScaleY(GetMatrix()); }
		
		public function set scaleY($value:Number): void
		{
			var matrix:Matrix = GetMatrix();
			TransformUtility.SetScaleY(matrix, $value);
			SetMatrix(matrix);
		}
		
		public function get rotation(): Number { return TransformUtility.GetRotation(GetMatrix()); }
		
		public function set rotation($rotation:Number): void
		{
			var matrix:Matrix = GetMatrix();
			TransformUtility.SetRotation(matrix, $rotation);
			SetMatrix(matrix);
		}
		
		override public function get matrix(): Matrix { return GetMatrix(); }
		
		override public function set matrix($value:Matrix): void { SetMatrix($value); }
	}
}